use core::cell::UnsafeCell;
use core::ops::{Deref, DerefMut};
use core::sync::atomic::{AtomicBool, Ordering};

// 自旋锁结构
pub struct SpinLock<T> {
    locked: AtomicBool,
    data: UnsafeCell<T>,
}

// 确保 SpinLock 可以在多线程环境中安全共享
unsafe impl<T> Sync for SpinLock<T> where T: Send {}

// 锁守卫，用于安全访问被保护的数据
pub struct SpinLockGuard<'a, T> {
    lock: &'a SpinLock<T>,
}

impl<T> SpinLock<T> {
    // 创建一个新的自旋锁
    pub const fn new(data: T) -> Self {
        SpinLock {
            locked: AtomicBool::new(false),
            data: UnsafeCell::new(data),
        }
    }

    // 获取锁，返回守卫
    pub fn lock(&self) -> SpinLockGuard<'_, T> {
        // 自旋等待直到获取锁
        while self
            .locked
            .compare_exchange_weak(false, true, Ordering::Acquire, Ordering::Relaxed)
            .is_err()
        {
            // 使用内存屏障降低 CPU 使用率
            core::hint::spin_loop();
        }

        SpinLockGuard { lock: self }
    }

    // 内部方法：解锁
    fn unlock(&self) {
        self.locked.store(false, Ordering::Release);
    }
}

// 实现守卫的 Deref 以访问数据
impl<T> Deref for SpinLockGuard<'_, T> {
    type Target = T;

    fn deref(&self) -> &T {
        unsafe { &*self.lock.data.get() }
    }
}

// 实现守卫的 DerefMut 以可变访问数据
impl<T> DerefMut for SpinLockGuard<'_, T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.lock.data.get() }
    }
}

// 守卫被丢弃时自动解锁
impl<T> Drop for SpinLockGuard<'_, T> {
    fn drop(&mut self) {
        self.lock.unlock();
    }
}
